/**
 * Created by haua on 2015/7/9.
 */
(function(){
    var _h = HMusic.prototype,
        dir = getDir(),
        music_next_file = dir+'hhh.music/next.png',
        music_pause_file = dir+'hhh.music/pause.png',
        music_play_file = dir+'hhh.music/play.png',
        music_on_file = dir+'hhh.music/on.png',
        music_off_file = dir+'hhh.music/off.png';

    /**
     * 播放控件，在html中引用了此js后，写上
     * var playMusic = new HMusic(["musics/mus1.mp3","musics/mus2.mp3","musics/mus3.mp3"]);就可以启动。
     * TODO 以后要把音乐的名字显示在按钮旁，现在先不做
     * @param musicList array|string 音乐的播放列表，数组格式，这里面的每个子项可以是对象，对象里面的src属性必须是音乐src哦
     * @param options Object
     * @param options.autoplay 是否自动播放
     * @param options.autonext 是否自动切换下一首
     * @param options.preload 如果不自动播放，是否预加载音频
     * @param options.btn
     * @param options.btn.num =2 按钮数量，如果音乐列表里只有一首歌，这个强制为1。参数只能是1或者2
     * @param options.isRandom =true 是否随机播放音乐
     * @param options.btnPosition ='right' 按钮应该在左还是右，可用的值为：'left'
     * @param options.onplay = null 当状态变成播放状态时
     * @param options.onpause = null 当变成暂停状态时
     *
     * ps.如果在手机测试时没有播放音乐，试试滑动屏幕或者点击屏幕任意位置，
     * 因为ios浏览器以及部分安卓手机浏览器都不允许打开页面马上播放音乐的，它们播放音乐的条件是：
     * 打开页面后，必须有用户对此网页的任意互动发生之后才能播放音乐
     */
    function HMusic(musicList,options){
        this.musicList = musicList instanceof Array?musicList:(musicList?[musicList]:[]);

        options = options || {};
        options.btn = options.btn || {};
        //按钮参数
        this.btn = options.btn || {};
        this.btn.num = typeof options.btn.num == 'number' ? options.btn.num : (!this.musicList.length||this.musicList.length==1 ?1:2);
        this.hasUI = !!this.btn.num;
        this.btn.position = options.btn.position || 'right';
        this.btn.autoShow = options.btn.autoShow !== false;

        this.autoplay = options.autoplay !== false;
        this.autonext = options.autonext !== false;
        this.isRandom = options.isRandom !== false;

        this.preload = !!options.preload;

        this.playingIndex = (this.isRandom&&this.musicList.length)?this._getRandomMusic():0;//正在播放的音乐是第几首，第一首是0。

        this.onplay = options.onplay||null; //两个供外部侦听的事件，当变成播放状态时
        this.onpause = options.onpause||null; //当变成暂停状态时

        if(this.btn.num>1){
            music_on_file = music_pause_file;
            music_off_file = music_play_file;
        }

        this.creatMusicDom();
    }

    /**
     * @param mode 如果这个参数被设置为play，则强制为播放
     */
    _h.play = function(mode){
        if(typeof mode == 'number'){
            this.next(mode);
        }else if(this.audio.paused||mode=="play"){
            this.audio.play();
        }else{
            this.pause();
        }
    };

    _h.pause = function(){
        this.audio.pause();
    };

    /**
     * 加载并播放音乐
     * <audio id="myAudio" autoplay="autoplay" loop="loop" >
     *		<source src="test.mp3" type="audio/ogg">
     *		<source src="test.mp3" type="audio/mpeg">
     *	</audio>
     */
    _h.creatMusicDom = function(){
        var musicObj = this.musicList[this.playingIndex],
            musicUrl = musicObj&&musicObj.src||musicObj;
        this.audio = document.createElement("AUDIO");
        this.audio.autoplay = this.autoplay;//
        this.audio.isLoadedmetadata = false;
        this.audio.touchstart = this.autoplay;
        this.audio.preload = this.preload;
        this.audio.audio = true;
        if(musicUrl)
            this.audio.src = musicUrl;
        document.body.appendChild(this.audio);

        var global = this;

        this.btn.autoShow && this.btn.num && !this._musicUI && this.createUI();

        //修复不能直接播放音频和预加载的bug
        (this.autoplay || this.preload) && window.addEventListener('touchstart', _startMusic,false);
        function _startMusic(){
            setTimeout(function(){
                if(global.preload&&!global.autoplay){ //修复预加载bug
                    global.audio.addEventListener('play',stopSound,false);
                    function stopSound(){
                        global.audio.pause();
                        global.audio.removeEventListener('play',stopSound,false);
                    }
                }
                global.play('play');
            },89);

            window.removeEventListener('touchstart', _startMusic,false);
        }

        //能直接播放音频的情况下,当媒介已开始播放时运行
        this.audio.addEventListener("play",function(){
            global.onplay && global.onplay();
            global._musicUI && global.updateUI();
            window.removeEventListener('touchstart', _startMusic,false);
        },false);

        //暂停播放事件
        this.audio.addEventListener("pause",function(){
            global._musicUI && global.updateUI();
            global.onpause && global.onpause();
        },false);

        //播放完成一曲后，自动播放下一曲
        this.autonext && this.audio.addEventListener("ended",function(){
            global.next();
            global.play("play");
        },false);

    };

    /**
     * 创建播放按钮
     *
     * @param mode 显示为播放中
     *
     * <div id="ssj_musicControl">
     *		<div class="play off" ></div>
     *		<div class="next" ></div>
     *	</div>
     */
    _h.createUI = function(mode){
        var global = this;
        //音乐控件div
        this._musicUI = document.createElement("DIV");
        this._musicUI.setAttribute("id", "ssj_musicControl");
        document.body.appendChild(this._musicUI);
        //播放按钮
        this._playBtn = document.createElement("DIV");
        this._playBtn.setAttribute("class", (mode=="play"?"play rotate":"play off"));
        this._musicUI.appendChild(this._playBtn);
        if(this.btn.num>1){//下一曲
            this._nextBtn = document.createElement("DIV");
            this._nextBtn.setAttribute("class", "next");
            this._musicUI.appendChild(this._nextBtn);
            this._nextBtn.addEventListener('touchend', global.next.bind(global),false);
        }

        //添加样式（ps.这里添加style的方法和上面的不一样哦）
        this.cssStart = "<style>";
        this.cssEnd = "</style>";
        this.cssStyle =
            "#ssj_musicControl{position: fixed;"+ (this.btn.position=='left'?'left: 40px;':'right: 10px;') +"top: 10px;z-index: 20000;}"
        + "#ssj_musicControl > div{display: inline-block;width:42px;height:42px;background-size: 100% 100%;background-repeat: no-repeat;margin-left: 8px;}"
        + "#ssj_musicControl .play{background-image: url("+music_on_file+");}"
        + "#ssj_musicControl .play.on{background-image: url("+music_on_file+");}"
        + "#ssj_musicControl .play.off {background-image: url("+music_off_file+");}"
        + "#ssj_musicControl .play.rotate {animation: rotating 1.2s linear infinite;-moz-animation: rotating 1.2s linear infinite;	/* Firefox */	-webkit-animation: rotating 1.2s linear infinite;	/* Safari 和 Chrome */	-o-animation: rotating 1.2s linear infinite;	/* Opera */	}"
        + "#ssj_musicControl .next{background-image: url("+music_next_file+");}";
        if(this.btn.num==1){
            /*动画*/
            this.cssStyle += "@keyframes rotating{"
            +	"0%   {transform: rotate(0deg);-ms-transform: rotate(0deg);}"
            +	"100% {transform: rotate(360deg);-ms-transform: rotate(360deg);}}"
            + "@-moz-keyframes rotating{" /* Firefox */
            +	"0%   {-moz-transform: rotate(0deg);}"
            +	"100% {-moz-transform: rotate(360deg);}}"
            + "@-webkit-keyframes rotating{" /* Safari 和 Chrome */
            +	"0%   {-webkit-transform: rotate(0deg);}"
            +	"100% {-webkit-transform: rotate(360deg);}}"
            + "@-o-keyframes rotating{" /* Opera */
            +	"0%  {-o-transform: rotate(0deg);}"
            +	"100% {-o-transform: rotate(360deg);}}";
        }
        //insertAdjacentHTML的第一个参数的可用值beforeBegin/afterBegin/beforeEnd/afterEnd
        this._musicUI.insertAdjacentHTML("beforeEnd",this.cssStart+this.cssStyle+this.cssEnd);

        this._playBtn.addEventListener('click', function(e){global.play()},true);
    };

    /**
     * 根据音乐更新UI状态
     */
    _h.updateUI = function(){
        if(!this.hasUI)return;
        if(this.audio.paused){
            this._playBtn.className = "play off";
        }else{
            this._playBtn.className = "play on rotate";
        }
    };

    /**
     * 下一曲
     */
    _h.next = function(index){
        if(typeof index == 'number')
            this.playingIndex = index;
        else if(this.isRandom){
            var radomNum = false,i = 0;
            while(i<5&&(radomNum==false||radomNum==this.playingIndex)){
                radomNum = this._getRandomMusic();
                i++;
            }
            this.playingIndex = radomNum;
        }else
            this.playingIndex = (++this.playingIndex) % (this.musicList.length);

        var musicObj = this.musicList[this.playingIndex],
            musicUrl = musicObj&&musicObj.src||musicObj;
        musicUrl && (this.audio.src = musicUrl);
        this.play("play");
    };

    _h._getRandomMusic = function(){
        return Math.floor(Math.random()*this.musicList.length);
    };

    /**
     * 替换现有的音乐列表
     * @param musicList string/array
     * */
    _h.changeMusicList = function(musicList){
        if(!(musicList&&musicList.length))return;
        var paused = this.audio.paused;
        this.musicList = musicList instanceof Array?musicList:[musicList];

        this.next(0);
        if(!paused)
            this.play("play");
    };

    _h.changeOptions = function(options){
        if(options){
            this.autoplay = typeof options.autoplay=='boolean'?options.autoplay:this.autoplay;
            this.autonext = typeof options.autonext=='boolean'?options.autonext:this.autonext;
            this.isRandom = typeof options.isRandom=='boolean'?options.isRandom:this.isRandom;
            this.onplay = typeof options.onplay=='function'?options.onplay:this.onplay; //两个供外部侦听的事件，当变成播放状态时
            this.onpause = typeof options.onpause=='function'?options.onpause:this.onpause; //当变成暂停状态时
        }
    };


    //获取当前js的目录
    function getDir() {
        var currUrl = document.currentScript&&document.currentScript.src
            ||document.scripts[document.scripts.length-1].src;
        return currUrl.substring(0,currUrl.lastIndexOf("/")+1);
    }

    //==================对HMusic的扩展用法==============================================================

    var musicObj = {}; //由于手机不能同时播放两个音频，即使两个audio标签都不能同时播，所以需要有个统一管理页面中的音频的地方

    /**
     * 返回一个整页通用的HMusic对象，一般是用于播放歌曲，这个需求下，同一时间只需有一个音频在播放即可
     * */
    function gloMusic(musicList,options){
        if(!musicObj['glo'])
            musicObj['glo'] = new HMusic([]);
        musicObj['glo'].changeMusicList(musicList);
        musicObj['glo'].changeOptions(options);

        return musicObj['glo']
    }

    /**
     * 一个能预加载所有音频的对象，用于做音效用，这个需求下，允许同时播放多个音频，以及触发播放到实际播放的时间要尽量短
     * 参数同 HMusic
     * */
    var _se = SoundEffect.prototype,
        optionForHMusic = {
            btn:{num:0},
            autoplay:false,
            autonext:false,
            isRandom:false,
            preload:true
        };
    function SoundEffect(musicList,options){
        this.musicList = [];
        this.playingIndex = 0;

        for(var i = 0,mNum = musicList.length;i<mNum;i++){
            this.preLoad(musicList[i]);
            this.musicList.push(new HMusic(musicList[i],optionForHMusic));
        }
    }
    _se.preLoad = function (music) {
        if(music) {
            var a = new Audio();
            a.src = music;
            a.load();
        }
    };
    _se.next = function(){
        this.playingIndex = ++this.playingIndex % this.musicList.length;
        this.musicList[this.playingIndex].play('play');
    };
    _se.play = function (i) {
        if(this.musicList[i])
            this.musicList[i].play('play');
    };

    //==================对HMusic的扩展用法==============================================================

    if(typeof define === 'function' && typeof define.amd === 'object' && define.amd){
        define(function(){
            return HMusic;
        });
    }else if(typeof module !== 'undefined' && module.exports){
        module.exports = HMusic;
    }else{
        window.HMusic = HMusic;
        window.gloMusic = gloMusic;
        window.SoundEffect = SoundEffect;
    }
}());

